#ifndef TB_REFLECTION_CONTAINER_H__
#define TB_REFLECTION_CONTAINER_H__

#include <list>
#include <vector>
#include <map>
#include <set>

#include "tbcore/predefined.hpp"

#include "type_traits.hpp"

TB_NAMESPACE_BEGIN

namespace reflection {

template <typename T>
struct is_list_container 
  : false_type {};

template <typename T>
struct is_vector_container 
  : false_type {};

template <typename T>
struct is_set_container 
  : false_type {};

template <typename T>
struct is_map_container 
  : false_type {};

template <typename T, typename A>
struct is_list_container<std::list<T, A> > 
  : true_type {};

template <typename T, typename A>
struct is_vector_container<std::vector<T, A> > 
  : true_type {};

template <typename K, typename T, typename C, typename A> 
struct is_map_container<std::map<K, T, C, A> > 
  : true_type {};

template <typename T, typename P, typename A>
struct is_set_container<std::set<T, P, A> > 
  : true_type {};

template <typename T> struct 
is_container 
  : boost::mpl::eval_if<
      boost::mpl::or_<is_list_container<T>, 
        boost::mpl::or_<is_vector_container<T>, 
          boost::mpl::or_<is_map_container<T>, 
            is_set_container<T> > > >, true_type, false_type>::type {};

template <typename T>
struct container_iterator {
  typedef typename boost::mpl::eval_if<is_const<T>, 
    const typename T::value_type, typename T::value_type>::type value_type;

  typedef typename boost::mpl::eval_if<is_const<T>, 
    const typename T::const_iterator, typename T::iterator>::type iterator_type;

  container_iterator(T x) : c_(x), it_(x.begin()) {}

  bool more() {
    it_ != c_.end();
  }

  value_type next() {
    return *(it_++);
  }

 private:
  T& c_;
  iterator_type it_;
};

} //namespace reflection

TB_NAMESPACE_END

#endif // TB_REFLECTION_CONTAINER_H__
